#ifndef TEST_GRAPHICS_TEST_SUITE_H
#	define TEST_GRAPHICS_TEST_SUITE_H

#include "test.h"

namespace dw {
	namespace test {

class TestSuite
:	public Test
{
public : //! @name Types definitions
	//! @{
	typedef Test base;
	//! @}

public : //! @name Construction & Destruction
	//! @{
	TestSuite(const std::string& name) : base(name) { ; }
	virtual ~TestSuite()
	{
		dwAssert(m_tests.empty(), "Did you forget to call teardown ?");
	}
	//! @}

public : //! @name Commands
	//! @{
	template< class T >
	bool add()
	{
		T* newTest = new T();

		dwLogInform("TestSuite %s::add( '%s' )\n", getName().c_str(), newTest->getName().c_str());
		
		m_tests.push_back(newTest);

		return true;
	}

	virtual bool setup()
	{
		dwLogInform("TestSuite %s::setup\n", getName().c_str());

		return true;
	}

	virtual bool run()
	{
		bool succeed = true;

		dwLogInform("TestSuite %s::run\n", getName().c_str());

		TestsCollection::const_iterator testsEnd = m_tests.end();

		for (TestsCollection::iterator testIt = m_tests.begin(); testIt != testsEnd; ++testIt)
		{
			Test* test = *testIt;

			bool testSucceed = false;
			if (test->setup())
			{
				testSucceed = test->run();
			}

			succeed = test->teardown() && testSucceed && succeed;
		}

		return succeed;
	}

	virtual bool teardown()
	{
		TestsCollection::const_iterator testsEnd = m_tests.end();

		for (TestsCollection::iterator testIt = m_tests.begin(); testIt != testsEnd; ++testIt)
		{
			delete *testIt;
		}

		m_tests.clear();

		dwLogInform("TestSuite %s::teardown\n", getName().c_str());

		return true;
	}
	//! @}

private : //! @name Types definitions
	//! @{
	typedef std::vector< dw::test::Test* > TestsCollection;
	//! @}

private : //! @name Data
	//! @{
	TestsCollection m_tests;
	//! @}
};

	} // namespace test
} // namespace dw

#endif // !TEST_GRAPHICS_TEST_SUITE_H
